iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 4
0
自我挑戰組

Ruby and Rails 的二三事系列 第 4

Ruby and Rails 的二三事 Day04 Symbol (符號)和 String(字串) 的差別

  • 分享至 

  • xImage
  •  

要了解Symbol (符號)和 String(字串) 的差別,
首先,我們得先複習一下Variable(變數) 和 String(字串):

Variable(變數)

變數,它本身並沒有形態。你可以把它想像成是「一張有寫著名字的標籤,貼在某個東西上面」,被貼的那個東西有形態,但標籤本身沒有。
 - from 為你自己學 Ruby and Rails

str = "I am string" 
# str 是一個變數,是個標籤,它被貼在"I am string"這個字串上面。
str.class => String
str.object_id => 70345293831900

String(字串)

String 是一個字串物件,同時也是一串由字母(characters)
 所組成的陣列(Array),所以許多陣列上的方法也都適用。

# 字串的內容可以任意修改。
str[3] => "m"
str.reverse => "gnirts ma I"
str[0] = "A"
p str => "A am string"

Symbol(符號)

A Symbol is the most basic Ruby object you can create. It's just a name and an internal ID. - rubylearing.com
Symbol objects represent names and some strings inside the Ruby interpreter.  from ruby-doc.org

Symbol(符號):

  • Symbol 是一個有名字的物件。
  • Symbol 是一個值,不是變數。
  • Symbol 具有唯一性(ID)的特徵,所以不能修改。

讓我們來看看下面的範例:

1. :name 是一個物件

:name.class => Symbol
:name.object_id => 87708

2. :name 是一個值,有他自己的名字,:name。

x = 2
=> 2
x = :name
=> :name   
  1.  :name 不是變數,無法被賦予值。
:name = "string"
=> syntax error, unexpected '=' ...
  1. #:name,具有唯一性。
#每次在印出"name"字串時,所得到的object_id 都不同
p "name".object_id => 70143757662660
p "name".object_id => 70143757662560
p "name".object_id => 70143757662460

#在印出:name的時候,只有一個object_id(唯一性)。
p :name.object_id => 1057308
p :name.object_id => 1057308
p :name.object_id => 1057308
  1. 無法對:name進行修改。
:name[0] => "n"
:name.reverse => NoMethodError
:name[0] = A => NameError (uninitialized constant A)
:name[0] = a => NameError (undefined local variable or method `a' for main:Object)


Symbol和String 之間的互相轉換

Transform between Symbol and String

name = :name
p name
str = name.to_s
p str
s2sym_1 = str.to_sym
s2sym_2 = str.intern
p s2sym_1 # convert from .to_sym
p s2sym_2 # convert from .intern

有其他方式會產生Symbol嗎?

Symbols are names - names of instance variables, names of methods, names of classes. - rubylearing.com
Thus if Fred is a constant in one context, a method in another, and a class in a third, the Symbol :Fred will be the same object in all three contexts.
 - ruby-doc.org

你可以用Google翻譯一下上面文字,或是直接看翻譯蒟蒻:
有四種方式會產生Symbol:

  • 實體變數(instant variable)
  • 定義方法(method)
  • 建立類別(Class); Class name 本身就是常數。
  • 常數(contant)

建立Symbol

class Cat
  @weight
  Hi = 1
  def meow
  end
end
puts :Cat.object_id.to_s + " is from class Cat"
puts :weight.object_id.to_s + " is from instance variable weight"
puts :Hi.object_id.to_s + " is from constant Hi"
puts :meow.object_id.to_s + " is from method meow"

# 在Repl.it上的執行結果
1047588 is from class Cat
1048668 is from instance variable weight
1048228 is from constant Hi
1048348 is from method meow
   

如果實體變數、方法、類別、常數命名都相同的時候會…?


什麼時候該用Symbol,什麼時候該用String?
If you use the contents of a string, this content may change, using a string.
If you use a fixed name or an identifier, use the symbol. - IBM opensource

簡單來說:
當你存放的內容是會變動時,使用String。
當你存放固定資料或是希望資料具有唯一性時,使用Symbol。


Symbol是用在什麼地方呢?

#這是在存取資料時常用的Hash

profile = {name: 'kk', age: 18, email: 'kk@5xruby.tw'} 
# 改成舊式的寫法:
profile = {:name => 'kk', :age => 18, :email => 'kk@5xruby.tw'}

#這是在Rails中常見的Migration檔的內容:

class CreateTodos < ActiveRecord::Migration[5.2]
  def change
    create_table :todos do |t|
      t.string :title
      t.string :description
      t.references :user, foreign_key: true
t.timestamps
    end
  end
end

#這是在Rails中常見的Model中的檔案內容:

class Todo < ApplicationRecord
  belongs_to :user
validates :title, :description, presence: true
end

冷知識:Symbol 命名的注意事項
Symbol 在命名時,不接受"\"字元:

#irb Mode
:name => :name
:n\ame => SyntaxError

以上,就是Symbol (符號)和 String(字串) 的差別。
鐵人賽,我們下次再見!!


上一篇
Ruby and Rails 的二三事 - Day03 Array and Hash
下一篇
Ruby on Rails 的二三事 - Day05 稍微介紹一下:Method 和 Block
系列文
Ruby and Rails 的二三事19
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言